<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>未来之窗-向量多层神经网络降维演示</title>
    <style>
        body {
            font-family: 'Microsoft YaHei', sans-serif;
            margin: 20px;
            line-height: 1.6;
        }
        .container {
            max-width: 1000px;
            margin: 0 auto;
        }
        .network-view {
            display: flex;
            justify-content: space-around;
            margin: 40px 0;
            align-items: center;
            flex-wrap: wrap;
        }
        .layer {
            text-align: center;
            padding: 15px;
        }
        .neuron-container {
            display: flex;
            flex-direction: column;
            gap: 8px;
            margin: 10px 0;
        }
        .neuron {
            width: 30px;
            height: 30px;
            border-radius: 50%;
            background: #e0e0e0;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            font-size: 12px;
            transition: all 0.3s;
        }
        .neuron.active {
            background: #4285f4;
            color: white;
        }
        .connection {
            margin: 0 10px;
            color: #666;
        }
        .vector-display {
            background: #f5f5f5;
            padding: 15px;
            border-radius: 6px;
            margin: 15px 0;
            font-family: monospace;
            overflow-x: auto;
        }
        button {
            padding: 10px 20px;
            background: #4285f4;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 16px;
        }
        button:hover {
            background: #3367d6;
        }
        .explanation {
            background: #f8f9fa;
            padding: 20px;
            border-radius: 6px;
            margin-top: 30px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>未来之窗-向量多层神经网络降维演示</h1>
        <p>模拟将10维输入向量通过2层神经网络"收缩"为3维输出向量的过程：</p>
        
        <div class="network-view">
            <div class="layer">
                <h3>输入层 (10维)</h3>
                <div class="neuron-container" id="inputLayer">
                    <!-- 10个神经元 -->
                </div>
            </div>
            
            <div class="connection">→</div>
            
            <div class="layer">
                <h3>隐藏层 (6维)</h3>
                <div class="neuron-container" id="hiddenLayer">
                    <!-- 6个神经元 -->
                </div>
            </div>
            
            <div class="connection">→</div>
            
            <div class="layer">
                <h3>输出层 (3维)</h3>
                <div class="neuron-container" id="outputLayer">
                    <!-- 3个神经元 -->
                </div>
            </div>
        </div>
        
        <div>
            <h3>输入向量 (10维):</h3>
            <div class="vector-display" id="inputVector">[0.2, 0.8, 0.1, 0.5, 0.9, 0.3, 0.7, 0.4, 0.6, 0.2]</div>
            
            <h3>隐藏层输出 (6维):</h3>
            <div class="vector-display" id="hiddenVector">[计算中...]</div>
            
            <h3>输出向量 (3维):</h3>
            <div class="vector-display" id="outputVector">[计算中...]</div>
            
            <button onclick="runNetwork()">运行降维计算</button>
        </div>
        
        <div class="explanation">
            <h3>降维原理说明：</h3>
            <ol>
                <li><strong>权重矩阵乘法</strong>：每层通过权重矩阵将高维向量映射到低维空间（如10×6的权重矩阵将10维→6维）</li>
                <li><strong>非线性激活</strong>：使用ReLU函数（max(0, x)）保留重要特征，过滤噪声</li>
                <li><strong>逐层收缩</strong>：通过多层处理，逐步将高维向量压缩为低维向量，同时保留关键信息</li>
            </ol>
        </div>
    </div>

    <script>
        // 初始化神经网络层显示
        function initLayers() {
            const inputLayer = document.getElementById('inputLayer');
            const hiddenLayer = document.getElementById('hiddenLayer');
            const outputLayer = document.getElementById('outputLayer');
            
            // 创建输入层神经元 (10维)
            for (let i = 0; i < 10; i++) {
                const neuron = document.createElement('div');
                neuron.className = 'neuron';
                neuron.textContent = i+1;
                inputLayer.appendChild(neuron);
            }
            
            // 创建隐藏层神经元 (6维)
            for (let i = 0; i < 6; i++) {
                const neuron = document.createElement('div');
                neuron.className = 'neuron';
                neuron.textContent = i+1;
                hiddenLayer.appendChild(neuron);
            }
            
            // 创建输出层神经元 (3维)
            for (let i = 0; i < 3; i++) {
                const neuron = document.createElement('div');
                neuron.className = 'neuron';
                neuron.textContent = i+1;
                outputLayer.appendChild(neuron);
            }
        }
        
        // 生成随机权重矩阵 (输入维度 × 输出维度)
        function generateWeights(inputDim, outputDim) {
            const weights = [];
            for (let i = 0; i < inputDim; i++) {
                const row = [];
                for (let j = 0; j < outputDim; j++) {
                    // 生成-0.5到0.5之间的随机权重
                    row.push(Math.random() - 0.5);
                }
                weights.push(row);
            }
            return weights;
        }
        
        // 矩阵乘法 (向量 × 权重矩阵)
        function multiplyVectorMatrix(vector, weights) {
            const inputDim = vector.length;
            const outputDim = weights[0].length;
            const result = new Array(outputDim).fill(0);
            
            for (let j = 0; j < outputDim; j++) {
                let sum = 0;
                for (let i = 0; i < inputDim; i++) {
                    sum += vector[i] * weights[i][j];
                }
                result[j] = sum;
            }
            
            return result;
        }
        
        // ReLU激活函数 (非线性变换)
        function reluActivation(vector) {
            return vector.map(x => Math.max(0, x)); // 只保留正数，过滤负数
        }
        
        // 运行神经网络降维
        function runNetwork() {
            // 10维输入向量
            const inputVector = [0.2, 0.8, 0.1, 0.5, 0.9, 0.3, 0.7, 0.4, 0.6, 0.2];
            
            // 生成权重矩阵 (输入层→隐藏层: 10×6, 隐藏层→输出层: 6×3)
            const weights1 = generateWeights(10, 6);
            const weights2 = generateWeights(6, 3);
            
            // 第一层计算: 10维 → 6维 (带激活函数)
            const hiddenPreActivation = multiplyVectorMatrix(inputVector, weights1);
            const hiddenVector = reluActivation(hiddenPreActivation);
            
            // 第二层计算: 6维 → 3维 (带激活函数)
            const outputPreActivation = multiplyVectorMatrix(hiddenVector, weights2);
            const outputVector = reluActivation(outputPreActivation);
            
            // 显示计算过程和结果
            visualizeProcess(inputVector, hiddenVector, outputVector);
            
            // 更新向量显示
            document.getElementById('hiddenVector').textContent = 
                '[' + hiddenVector.map(x => x.toFixed(4)).join(', ') + ']';
            document.getElementById('outputVector').textContent = 
                '[' + outputVector.map(x => x.toFixed(4)).join(', ') + ']';
        }
        
        // 可视化神经网络激活过程
        function visualizeProcess(input, hidden, output) {
            const inputNeurons = document.querySelectorAll('#inputLayer .neuron');
            const hiddenNeurons = document.querySelectorAll('#hiddenLayer .neuron');
            const outputNeurons = document.querySelectorAll('#outputLayer .neuron');
            
            // 重置所有神经元状态
            document.querySelectorAll('.neuron').forEach(neuron => {
                neuron.classList.remove('active');
                neuron.style.opacity = 0.5;
            });
            
            // 激活输入层神经元 (值越大越亮)
            inputNeurons.forEach((neuron, i) => {
                neuron.classList.add('active');
                neuron.style.opacity = 0.5 + input[i] * 0.5; // 根据向量值调整亮度
            });
            
            // 延迟激活隐藏层
            setTimeout(() => {
                hiddenNeurons.forEach((neuron, i) => {
                    neuron.classList.add('active');
                    neuron.style.opacity = 0.5 + (hidden[i] / Math.max(...hidden || [1])) * 0.5;
                });
                
                // 延迟激活输出层
                setTimeout(() => {
                    outputNeurons.forEach((neuron, i) => {
                        neuron.classList.add('active');
                        neuron.style.opacity = 0.5 + (output[i] / Math.max(...output || [1])) * 0.5;
                    });
                }, 800);
            }, 800);
        }
        
        // 初始化页面
        initLayers();
    </script>
</body>
</html>
